import 'package:bordered_text/bordered_text.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:find_friend/common/common_widget.dart';
import 'package:find_friend/common/play_audio_flr.dart';
import 'package:find_friend/const/const.dart';
import 'package:find_friend/pages/login&register/model/shared_user_info.dart';
import 'package:find_friend/pages/mine/mine_photos_wall.dart';
import 'package:find_friend/pages/mine/mine_preview_page.dart';
import 'package:find_friend/pages/mine/view/mine_tag_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';
import 'dart:math';

import 'model/starmodel.dart';

class CircleHeadWidget extends StatefulWidget {
  
  final List<HomeRecommdModel> list;
  final Function() onHidden;
  const CircleHeadWidget({Key key, this.list, this.onHidden}) : super(key: key);
  
  @override
  _CircleHeadWidgetState createState() => _CircleHeadWidgetState();
}

class _CircleHeadWidgetState extends State<CircleHeadWidget> with SingleTickerProviderStateMixin {

  double progress = 0;
  AnimationController _controller;
  Animation<double> _animation;
  double beingX = 0;
  double endX = 0;
  int beginTime;
  HomeRecommdModel _homemodel;
  final _spring = const SpringDescription(
    mass: 30,
    stiffness: 1000,
    damping: 1,
  );

  @override
  void initState() {
    super.initState();
    _controller = AnimationController.unbounded(vsync: this)
      ..addListener(() {
        setState(() {
          progress = _animation.value;
        });
        if(_controller.status == AnimationStatus.completed) _searchModel();
      });
  }

  @override
  void didUpdateWidget(CircleHeadWidget oldWidget) {
    if(_homemodel == null) _searchModel();
    super.didUpdateWidget(oldWidget);
  }

  void _searchModel() {
    HomeRecommdModel _model;
    widget.list.forEach((element) { 
      if(element?.offset != null) {
        if(_model == null) _model = element;
        if(_model.offset > element.offset) {
          _model = element;
        }
      }
    });

    setState(() {
      _homemodel = _model;
    });
  }

  void _updateProgress(double p) {
    setState(() {
      if(p < 0){
        if(progress >= 1) progress = 0; // 顺序不能乱
        progress += 0.01;
      } else {
        progress -= 0.01;
        if(progress <= 0) progress = 1;
      }
    });
  }

  HomeRecommdModel _getRandomModel(int index) {
    if(widget.list.isEmpty || index >= widget.list.length) return null;
    return widget.list[index];
  }


  double _normalizeVelocity(Offset velocity, Size size) {
    final normalizedVelocity = Offset(
      velocity.dx / size.width,
      velocity.dy / size.height,
    );
    return -normalizedVelocity.distance;
  }

  void _runAnimation(Offset velocity, Size size) {
    double temp = beingX - endX;
    double _currPro = temp / size.width;
    double begin = 0;
    double end = 0;
    begin = progress;
    end = progress + _currPro;
    _animation = _controller.drive(
      Tween(
        begin: begin,
        end: end,
      ),
    );
    final simulation =
        SpringSimulation(_spring, 0, 1, _normalizeVelocity(velocity, size));

    _controller.animateWith(simulation);
  }

  Widget _create(double angle, int index, double left, double radiusA){
    return StackChild(
              beginAngle: angle,
              progress: progress,
              index: index,
              left: left,
              raduisA: radiusA,
              model: _getRandomModel(index),
            );
  }

  List<Widget> _createChildern(BuildContext context) {

    List<Widget> res = [];
    final Size size = MediaQuery.of(context).size;
    final raduiA = size.width * 0.33;
    final left = (size.width - raduiA * 2) / 2.0;
    for(var i = 10.0; i<= 330; i+=40) {
      res.add(_create(i, i ~/ 40, left - 20, raduiA));
    }
    return res;
  }

  @override
  Widget build(BuildContext context) {
    
    final size = MediaQuery.of(context).size;

    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onHorizontalDragDown: (details) => beginTime = DateTime.now().millisecondsSinceEpoch,
      onHorizontalDragStart: (details) {
        beingX = details.localPosition.dx;
        _controller?.stop(canceled: true);
      },
      onHorizontalDragUpdate: (details){
        if(details.delta.dx == 0) return;
        endX = details.localPosition.dx;
        _updateProgress(details.delta.dx);
      },
      onTap: widget.onHidden,
      onHorizontalDragEnd: (details){
        if((beingX - endX).abs() < 10) {
          _searchModel();
          return;
        }
        int endTime = DateTime.now().millisecondsSinceEpoch;
        if(endTime - beginTime < 300) {
          _runAnimation(details.velocity.pixelsPerSecond, size);
        } else {
          _searchModel();
        }
      },
      child: Stack(
        children: [
          Center(
            child: Container(
              height: 200,
              margin: const EdgeInsets.only(bottom: 90),
              child: Stack(
                children: _createChildern(context),
              )
            ),
          ),
          Positioned(
            bottom: -40,
            child: _UserInfo(model: _homemodel,)
          ),
        ],
      ),
    );
  }
}

class StackChild extends StatelessWidget {
  
  final double progress; // 角度 0 ~ 1
  final double top; // 上边距
  final double left; // 左边距
  final double beginAngle; // 开始角度
  final HomeRecommdModel model;
  final int index;
  final double raduisA; // 椭圆的长半轴
  StackChild({
    Key key, 
    this.raduisA,
    this.progress = 0, 
    this.top = 0,
    this.left = 0,
    this.beginAngle = 0,
    this.model,
    this.index,
  }) : super(key: key);

  /// 圆形
  Offset _circleComputeOffset(double angle, Offset center, double radius) {
    double radian = pi / 180.0 * (angle + beginAngle);

    final adius = 80;

    double x = center.dx + cos(radian) * adius;
    double y = center.dy + sin(radian) * adius;
    return Offset(x, y);
  }

  /// 椭圆
  Offset _ovalComputeOffset(double angle, Offset center, double raduis) {
    double radian = pi / 180.0 * (angle + beginAngle);
    
    final ovalA = raduis; // 长半径
    final ovalB = 40.0;   // 短半径

    Offset res;
    double x = ovalA * cos(radian);
    double y = ovalB * sin(radian);
    res = Offset(x, y);
    return Offset(res.dx + center.dx, res.dy + center.dy);
  }

  /// 斜椭圆
  Offset _ovalTitlComputeOffset(double angle, Offset center, double raduis) {
    double radian = pi / 180.0 * (angle + beginAngle);
    
    final ovalA = raduis; // 长半径
    final ovalB = 40.0;   // 短半径
    final titlAngle = - pi / 360 * 10.0; // 倾斜角度

    Offset res;
    double x = ovalA * cos(radian) * cos(titlAngle) - ovalB * sin(radian) * sin(titlAngle);
    double y = ovalA * cos(radian) * sin(titlAngle) - ovalB * sin(radian) * cos(titlAngle);
    res = Offset(x, y);
    return Offset(res.dx + center.dx, res.dy + center.dy);
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    Offset center = Offset((size.width - raduisA) / 2, 150.0 - 80); // 圆中心点
    Offset ofset = _ovalComputeOffset(progress * 360, center, raduisA);
    double imageH = ofset.dy - 50;
    bool isshow = ofset.dy + top < 50;
    double leftoffset = ofset.dx + left;
    if(!isshow){
      model?.offset = (leftoffset - raduisA).abs();
    } else {
      model?.offset = null;
    }
    
    return Positioned(
      top: 80,
      left: leftoffset,
      child: Offstage(
        offstage: isshow,
        child: Container(
          padding: EdgeInsets.only(top: top ?? 0),
          child: Column(
            children: [
              BorderedText(
                strokeWidth: 1.0,
                strokeColor: Colors.black12,
                child: Text(
                  model?.nickname ?? '',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 14 / 50 * imageH,
                  ),
                ),
              ),
              Draggable(
                feedback: CustomCircleAvatar(size: imageH,url: model?.avatar,),
                data: model,
                child: InkWell(
                  onTap: (){
                    push(context, MinePreviewPage(mobile: model.mobile));
                  },
                  child: Container(
                    decoration: BoxDecoration(
                      border: Border.all(color: Colors.white, width: 0.5),
                      shape: BoxShape.circle,
                      boxShadow: [
                        BoxShadow(blurRadius: 12, spreadRadius: -2, color: Colors.black)
                      ]
                    ),
                    child: CustomCircleAvatar(size: imageH,url: model?.avatar,)
                  ),
                )
              )
            ],
          )
        ),
      ),
    );
  }
}


class _UserInfo extends StatelessWidget {

  final HomeRecommdModel model;
  static const heroPerfix = "homerecommend";

  const _UserInfo({Key key, this.model}) : super(key: key);

  String _photoNum() {
    // if((model.photowall?.length ?? 0) <= 3) return "";
    return "x${model?.photowall?.length ?? 0}";
  }
  @override
  Widget build(BuildContext context) {
    
    final size = MediaQuery.of(context).size;

    return SafeArea(
      child: Padding(
        padding: const EdgeInsets.only(left: 26),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            AudioFlrWidget(signvoice: model?.signvoice, audiobackImgName: "assets/home_yinpindi.png",),
            Row(
              children: [
                Image.asset(model?.gender == 1 ? "assets/nan.png" : "assets/nv.png"),
                Text(model?.zodiac ?? "天蝎座", style: instanceTextStyle(11, APP_main_color),),
                SizedBox(width: 5,),
                MineTagWidget(label: model?.label,)
              ],
            ),
            Container(
              margin: const EdgeInsets.only(right: 100),
              child: Text(
                model?.bio ?? "什么都没有~", 
                style: TextStyle(color: Colors.white, fontSize: 11,),
              ),
            ),
            Container(
              height: 53.5,
              width: size.width,
              margin: const EdgeInsets.only(right: 53, top: 11),
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  Container(
                    height: 53.5,
                    width: (53.5 + 5) * 3.5,
                    child: ListView.builder(
                      itemCount: model?.photowall?.length ?? 0,
                      itemExtent: 53.5 + 5,
                      scrollDirection: Axis.horizontal,
                      itemBuilder: (context, index){
                        final tagStr = "homeavatar" + index.toString();
                        return GestureDetector(
                          onTap: () async {
                            List<FileModel> temp = model.photowall.map((e) => FileModel(id: 0, url: e.url)).toList();
                            Navigator.push(context, PageRouteBuilder(
                                pageBuilder: (BuildContext context, Animation animation,
                                    Animation secondaryAnimation) {
                                  return new FadeTransition(
                                    opacity: animation,
                                    child: MinePhotoWallPage(heroTag: heroPerfix + tagStr, list: temp,),
                                  );
                                })
                            );
                          },
                          child: Container(
                            margin: const EdgeInsets.only(right: 5),
                            decoration: BoxDecoration(
                              border: Border.all(color: Colors.white, width: 0.5),
                              borderRadius: BorderRadius.circular(10),
                            ),
                            child: PhysicalModel(
                              color: Colors.transparent,
                              borderRadius: BorderRadius.circular(10),
                              clipBehavior: Clip.antiAlias,
                              child: Hero(
                                tag: heroPerfix + tagStr,
                                child: CachedNetworkImage(
                                  imageUrl: model?.photowall[index].url ?? "",
                                  fit: BoxFit.cover,
                                ),
                              ),
                            ),
                          ),
                        );
                    }),
                  ),
                  Padding(
                    padding: const EdgeInsets.only(bottom: 5.0, left: 5),
                    child: Offstage(
                      offstage: model?.photowall == null,
                      child: Text(_photoNum(), style: instanceTextStyle(11, Colors.white),)
                    ),
                  )
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
